package org.apli.haiam.admin.jsf.managed;

import com.apli.controladores.Aplinfo;
import com.apli.controladores.AplinfoFactoryBean;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.ResourceBundle;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;
import org.apli.haiam.admin.entidades.UsuarioAdmin;
import org.apli.haiam.ejb.entidades.AdmEmpleado;
import org.apli.haiam.ejb.entidades.AdmUsuario;
import org.apli.haiam.ejb.interfaces.AdministradorLoginHaiam;
import org.apli.haiam.ejb.interfaces.AdministradorPerfilHaiam;
import org.apli.jsf.managed.JsfBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Clase backing Bean que administra la entidad AdmUsuario. <p>
 * <p>
 * <H6>Soporte:HAIAM
 * <I>david_s_1086@hotmail.com,david.carranza@haiam.gob.ec</I></H6>
 *
 * @author david Carranza
 * @version 1.0 30/07/2014
 */
@ManagedBean
@ViewScoped
public class JsfUsuario extends JsfBean<AdmUsuario> {

    private boolean valido = true;
    final Logger log = LoggerFactory.getLogger(JsfUsuario.class);
    @EJB
    private AdministradorPerfilHaiam adminPerfil;
    @EJB
    private AdministradorLoginHaiam adminLogin;
    private String consultaUsername;
    private AdmEmpleado persona;
    private int habilita = 0;
    private List<AdmUsuario> listaContacto;

    /**
     * Constructor por defecto.
     */
    public JsfUsuario() {
        // super();
    }

    /**
     * Inicializa los datos miembros.
     */
    @Override
    protected void inicializar() {
        object = new AdmUsuario();
        
        persona = new AdmEmpleado();
        habilita = 0;
        object.setEstado((short) 1);
        listaContacto = new ArrayList<>();
       
        cargarListaUsuarioEmpleado();
    }

    /**
     * Método optener conexión a EJB de Perfiles.
     */
    @Override
    protected void cargarEjb() {
        super.cargarEjb();
        if (adminPerfil == null) {
            String ejbPath = null;
            try {
                ResourceBundle property = getProperties();
                String ORBContext = property.getString("ORBContext");
                String ejbContextPath = property.getString("ejb.context.path.admin");
                ejbPath = ORBContext + ejbContextPath + "/AdministradorPerfilBeanHaiam";
                adminPerfil = (AdministradorPerfilHaiam) AplinfoFactoryBean.lookupBean(ejbPath, false);
            } catch (Exception e) {
                log.error("cargarEjbPerfil() {} - {} ", ejbPath, e.getMessage());
            }
        }
        if (adminLogin == null) {
            String ejbPath = null;
            try {
                ResourceBundle property = getProperties();
                String ORBContext = property.getString("ORBContext");
                String ejbContextPath = property.getString("ejb.context.path.admin");
                ejbPath = ORBContext + ejbContextPath + "/AdministradorLoginBeanHaiam";
                adminLogin = (AdministradorLoginHaiam) AplinfoFactoryBean.lookupBean(ejbPath, false);
            } catch (Exception e) {
                log.error("cargarEjbLogin() {} - {} ", ejbPath, e.getMessage());
            }
        }
    }

    @Override
    protected ResourceBundle getProperties() {
        return ResourceBundle.getBundle("aplicacion");
    }

    /**
     * Graba el registro asociado al objeto que se administra en la página.
     *
     * @return null, se mantiene en la página invocada.
     */
    @Override
    public String grabarAction() {
        FacesContext context = FacesContext.getCurrentInstance();
        try {
            validar();
        } catch (Exception e) {
        }
        if (object.getIdUsuario() == null) {
            if (persona != null && persona.getIdEmpleado() != null) {
                object.setAdmEmpleado(persona);
               
            } else {
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Falta agregar empleado", "Falta agregar empleado"));
                return null;
            }
            try {
                object.setPassword(Aplinfo.encriptarHash(object.getPassword()));
                object.setFechaCreacion(admin.getFechaDb());
                object.setFechaUltimoAcceso(new Date());
                admin.crear(object, FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user"));
                inicializar();
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(bundle.getString("msg.grabar")));
            } catch (Exception e) {
                object.setIdUsuario(null);
                log.error("grabarAction() {} ", e.getMessage());
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), e.getMessage()));
            }
        } else {
            try {
                object.setPassword(Aplinfo.encriptarHash(object.getPassword()));
                admin.modificar(object, FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user"));
                inicializar();
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(bundle.getString("msg.grabar")));
            } catch (Exception e) {
                log.error("grabarAction() {} ", e.getMessage());
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), e.getMessage()));
            }
        }
        return null;
    }

    public List<SelectItem> getSelectedItemEmpleadosNoUsuarios() {
        try {
            //List<AdmEmpleado> datos = admin.ejecutarQueryNativoLista("select * from adm_empleado where id_empleado not in (select id_empleado from adm_usuario where id_empleado is not null) order by nombre", AdmEmpleado.class);
            List<AdmEmpleado> datos = (List<AdmEmpleado>) admin.queryEJB("select e from AdmEmpleado e where NOT EXISTS  (select a from e.admUsuarioList a ) order by e.nombre");
            
            List<SelectItem> items = new ArrayList<>();
            for (AdmEmpleado obj : datos) {
                items.add(new SelectItem(obj, obj.getCedula() + " - " + obj.getNombreFull()));
            }
            return items;
        } catch (Exception e) {
            log.error("getSelectedItemEmpleadosNoUsuarios() {} ", e.getMessage());
        }
        return null;
    }

    public List<SelectItem> getSelectedItemContactosNoUsuarios() {
//        try {
//            List<AdmContacto> datos = admin.ejecutarQueryNativoLista("select * from adm_contacto where id_contacto not in (select id_contacto from adm_usuario where id_contacto is not null) order by nombre", AdmContacto.class);
//            List<SelectItem> items = new ArrayList<SelectItem>();
//            for (AdmContacto obj : datos) {
//                items.add(new SelectItem(obj, obj.getIdentificacion() + " - " + obj.getNombre()));
//            }
//            return items;
//        } catch (Exception e) {
//            log.error("getSelectedItemEmpleadosNoUsuarios() {} ", e.getMessage());
//        }
        return null;
    }

    public void cargarListaUsuarioEmpleado() {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";
        if (admin == null) {
            lista = null;
            return;
        }
        try {
            lista = admin.listarNotNullOrdenada(object.getClass(), "admEmpleado", "username", true);
        } catch (Exception e) {
            log.error("{}: {} ", nombreMetodo, e);
        }
    }

    
    public void limpiarListener() {
        if (object != null) {
            object.setUsername("");
        }
    }

    public String activarAction(AdmUsuario obj) {
        FacesContext context = FacesContext.getCurrentInstance();
        try {
            if (obj.getEstado() == 0) {
                obj.setEstado((short) 1);
            } else {
                obj.setEstado((short) 0);
            }
            admin.modificar(obj, FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user"));
            inicializar();
            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(bundle.getString("msg.grabar")));
        } catch (Exception e) {
            log.error("grabarAction() {} ", e.getMessage());
            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), e.getMessage()));
        }
        return null;
    }

    public List<AdmEmpleado> personaAutocompleteAction(String dato) {
        List<AdmEmpleado> result = new ArrayList<>();
        if (dato.length() < 9) {
            return null;
        }
        // dato = dato.toUpperCase();
        try {
            result = adminObject.listarIniciaCon(AdmEmpleado.class, "cedula", dato);

        } catch (Exception ex) {
            log.error("icusNormativaAutocompleteAction(...) " + ex);
        }
        return result;




    }

   
    /**
     * Obtiene la lista de objetos en un DataModel.
     */
    @Override
    public void cargarDataModel() {
        if (admin == null) {
            return;
        }
        try {
            model = new ListDataModel(admin.listarOrdenada(object.getClass(), "username", true));
        } catch (Exception e) {
            log.error("getDataModel() {} ", e.getMessage());
            model = null;
        }
    }

    /**
     * Obtiene la lista de objetos en un DataModel.
     */
    public void cargarPersonaListener() {
        if (admin == null) {
            return;
        }
        try {

            persona = new AdmEmpleado();
            persona = object.getAdmEmpleado();

        } catch (Exception e) {
            log.error("getDataModel() {} ", e.getMessage());
        }
    }

    /**
     * Genera una nueva contraseña para el usuario.
     *
     * @return la lista
     */
    public String generarContrasena() {

        //FacesContext context = FacesContext.getCurrentInstance();
        try {
            object.setPassword(Aplinfo.getRandomPassword());
        } catch (Exception e) {
            log.error("getDataModel() {} ", e.getMessage());
        }


        return null;
    }

    /**
     * Obtiene una lista de objetos de tipo SelectedItem.
     *
     * @return la lista
     */
    @Override
    public List<SelectItem> getSelectedItem() {
        try {
            List<AdmUsuario> datos = admin.listarOrdenada(object.getClass(), "username", true);
            List<SelectItem> items = new ArrayList<>();
            for (AdmUsuario obj : datos) {
                if (obj.getAdmMedico() == null) {
                    items.add(new SelectItem(obj, "[EMPLEADO] " + obj.getUsername() + " - " + obj.getAdmEmpleado().getNombreFull() + " [" + obj.getAdmEmpleado().getAdmCargo().getNombre() + "]"));
                } else {
                    items.add(new SelectItem(obj, "[MEDICO] " + obj.getUsername() + " - " + obj.getAdmMedico().getAmeNombreFull()));
                }
            }
            return items;
        } catch (Exception e) {
            log.error("getSelectedItem() {} ", e.getMessage());
        }
        return null;
    }

    public String verificarAction() {
        FacesContext context = FacesContext.getCurrentInstance();
        inicializar();
        try {
            UsuarioAdmin user = (UsuarioAdmin) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user");
            if (!adminLogin.isUsuarioAD(user.getUsername(), user.getClave2())) {
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "usernameConsulta").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "No está autorizado a crear o modificar usurios!", "No está autorizado a crear o modificar usurios!"));
                return null;
            }
            if (adminLogin.existeUsuarioAD(consultaUsername, user)) {
                object = (AdmUsuario) adminLogin.getUsuario(consultaUsername, user).getUser();

//                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "username").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, bundle.getString("msg.mail.error"), "ApliUsuarioImp"));
            } else {
//                object = new AdmUsuario();
//                object.setUsername(consultaUsername);
//                object.setPassword(adminGlobal.encriptarMD5(adminGlobal.getRandomPassword()));
//                object.setUsuarioExterno((short) 1);
//                object.setEstado((short) 1);
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "usernameConsulta").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "El usuario no es parte del Directorio", "El usuario no es parte del Directorio"));
            }
        } catch (Exception e) {
            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "usernameConsulta").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), e.getMessage()));
        }
        consultaUsername = "";
        return null;
    }

    public String editarUsuarioContactoAction(AdmUsuario obj) {
        inicializar();
        object = obj;
       
        return null;
    }

    public String editarUsuarioEmpleadoAction(AdmUsuario obj) {
        inicializar();
        object = obj;
        persona = obj.getAdmEmpleado();
        return null;
    }

    public String validar() throws Exception {
//        FacesContext context = FacesContext.getCurrentInstance();zz
//        valido = true;
//        if (admin.existePorCampo(object.getClass(), "username", object.getUsername())) {
//            valido = false;
//            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Username ya existe", "Username ya existe"));
//        }
        return null;
    }

    public int getHabilita() {
        return habilita;
    }

    public void setHabilita(int habilita) {
        this.habilita = habilita;
    }

    public List<AdmUsuario> getListaContacto() {
        return listaContacto;
    }

    public void setListaContacto(List<AdmUsuario> listaContacto) {
        this.listaContacto = listaContacto;
    }

   

    public void setEstado(boolean estado) {
        if (object != null) {
            object.setEstado(estado ? (short) 1 : (short) 0);
        }
    }

    public boolean isEstado() {
        if (object != null) {
            return object.getEstado() == 1;
        }
        return false;
    }

    public String getConsultaUsername() {
        return consultaUsername;
    }

    public AdmEmpleado getPersona() {
        return persona;
    }

    public void setPersona(AdmEmpleado persona) {
        this.persona = persona;
    }

    public void setConsultaUsername(String consultaUsername) {
        this.consultaUsername = consultaUsername;
    }
}
